package com.ly.pic.init;

import com.alibaba.fastjson.JSON;
import com.ly.pic.config.Config;
import com.ly.pic.service.FeatureExtractionAGG19Service;
import lombok.extern.slf4j.Slf4j;
import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.factory.Nd4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Component
public class InitExtraction {


    @Autowired
    private FeatureExtractionAGG19Service featureExtractionAGG19Service;
    public static Config config = null;




    @PostConstruct
    private void init() throws IOException {
        //读取配置文件
        config = readConfig();
        if (config.isLoadFeatures()) {
            agg19();
            //加载模型后重写cvs
            deleteCvs();
            //重新保存
            saveFeatureCvs();
        } else {
            //加载cvs中的向量，保存到内存
            loadVectorsFromCsv();
        }
    }

    private void saveFeatureCvs() throws IOException {
        List<INDArray> featureList = featureExtractionAGG19Service.featureList;
        // 定义CSV文件的路径
        Path path = Paths.get("feature", "features.json");
        // 检查并创建目录路径（如果不存在）
        if (!Files.exists(path.getParent())) {
            Files.createDirectories(path.getParent());
        }
        List<String> jsonList = featureList.stream()
                .map(vector -> {
                    double[] vectorArray = vector.toDoubleVector();
                    return JSON.toJSONString(vectorArray);
                })
                .collect(Collectors.toList());
        if (!Files.exists(path.getParent())) {
            Files.createDirectories(path.getParent());
        }
        Files.write(path, jsonList);
    }

    // 从JSON文件加载向量并将其保存到List<INDArray>中的方法
    public void loadVectorsFromCsv() throws IOException {
        Path path = Paths.get("feature", "features.json");
        List<String> jsonList = Files.readAllLines(path);
        List<INDArray> featureList = new ArrayList<>();
        for (String json : jsonList) {
            float[] vectorArray = JSON.parseObject(json, float[].class);
            INDArray vector = Nd4j.create(vectorArray);
            featureList.add(vector);
        }
        featureExtractionAGG19Service.addAllFeature(featureList);
    }

    private static void deleteCvs() {
        // Construct the file path using Paths
        Path filePath = Paths.get(System.getProperty("user.dir"), "feature", "features.json");
        try {
            if (Files.exists(filePath) && Files.isRegularFile(filePath)) {
                Files.delete(filePath);
                log.info("Deleted: {}", filePath.getFileName());
            } else {
                log.info("The file does not exist or is not a file.");
            }
        } catch (IOException e) {
            log.error("An error occurred while trying to delete the file: {}", e.getMessage());
        }
    }


    private Config readConfig() throws IOException {
        // 读取配置文件
        String jsonContent = readFileAsString("pic_config.json");
        log.info("配置:{}", jsonContent);
        return JSON.parseObject(jsonContent, Config.class);
    }

    private String readFileAsString(String filePath) throws IOException {
        return new String(Files.readAllBytes(Paths.get(filePath)));
    }

    public static List<INDArray> loadFromCSV(String filePath) throws IOException {
        List<INDArray> vectors = new ArrayList<>();
        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
            String line;
            while ((line = reader.readLine()) != null) {
                String[] tokens = line.split(";");
                double[] values = new double[tokens.length];
                for (int i = 0; i < tokens.length; i++) {
                    values[i] = Double.parseDouble(tokens[i]);
                }
                INDArray vector = Nd4j.create(values);
                vectors.add(vector);
            }
        }
        return vectors;
    }


    private void agg19() throws IOException {
        List<Path> list = new ArrayList<>();
        Path projectRoot = Paths.get("").toAbsolutePath();
        Path images = projectRoot.resolve("images");
        DirectoryStream<Path> paths = Files.newDirectoryStream(images);
        for (Path path : paths) {
            if (Files.isRegularFile(path)) {
                list.add(path);
            }
        }
        long l = System.currentTimeMillis();
        int index = 0;
        for (Path path : list) {
            index++;
            try {
                featureExtractionAGG19Service.setFeature(path.toAbsolutePath().toString());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        System.out.println("特征提取耗时：" + (System.currentTimeMillis() - l));
    }

}
